package pATT.core.visual;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.SystemColor;
import java.io.File;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.JWindow;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.DefaultMutableTreeNode;

import pATT.core.Utils;
import pATT.logger.Logger;
import pATT.logger.Message;
import pATT.profile.Profile;
import pATT.profilingAlgorithm.ProfilingAlgorithm;
import pATT.visualize.VisualizeAlgorithm;

/**
 * @author
 */
public class VisualizePanel extends JPanel {
	//~ Static fields/initializers -----------------------------------------------------------------
	
	/**
	 *
	 */
	private static final long serialVersionUID = 1L;
	
	//~ Instance fields ----------------------------------------------------------------------------
	
	//	private JScrollPane jScrollPane1 = null;
	//	private JTextArea jTextArea3 = null;
	/** Instancia para el Editor del algortimo de toma de decisiones seleccionado*/
	protected GenericObjectEditor m_VisualizeEditor = new GenericObjectEditor();
	/** Un thread en el que correra el algoritmo */
	/** Perfil ingresado por el usuario*/
	protected Profile profile = new Profile();
	private Hashtable<String, ProfilingAlgorithm> algoritms = new Hashtable<String, ProfilingAlgorithm>();
	private Hashtable<String, String> hash = new Hashtable<String, String>();
	private JButton jButton1 = null;
	private JButton jChooserButton = null;
	private JPanel jChooserPanel1 = null;
	private JPanel jPanel = null;
	private JPanel jPanel3 = null;
	/**
	 * variable graficas
	 */
	private JPanel jVisualizePanel = null; //  @jve:decl-index=0:visual-constraint="10,559"
	private JProgressBar jProgressBar = null;
	private JScrollPane jScrollPane3 = null;
	private JTextField jChooseTextField = null;
	private JTree jTree = null;
	private JWindow jWindow = null; //  @jve:decl-index=0:visual-constraint="797,10"
	private ProfilingAlgorithm algorithm = null;
	
	private JButton jButtonSave = null;
	/**  Filtro para asegurarse que se guarde o cargue un perfil */
	protected FileFilter m_ProfFilter = new ExtensionFileFilter(".jpg","Archivo grafico (*.jpg)");
	/** File chooser para seleccionar archivos desde el home del user*/
	protected JFileChooser m_FileChooser = new JFileChooser(new File(System.getProperty("user.dir")));
	/**
	 * Panel donde se almacena el grafico
	 */
	protected JPanel panel = null;
	protected ResolutionImage resol = new ResolutionImage();	
	
	protected VisualizeAlgorithm visAlgorithm = null;

	private JScrollPane jScrollPane4 = null;

	private JTextArea jTextArea = null;
	
	//~ Constructors -------------------------------------------------------------------------------
	
	/**
	 * Crea un nuevo objeto VisualizePanel.
	 */
	public VisualizePanel() {
		super();
		initialize();
	}
	
	//~ Methods ------------------------------------------------------------------------------------
	
	/**
	 * This method initializes jButton1
	 *
	 * @return javax.swing.JButton
	 */
	public JButton getJButton1() {
		if (jButton1 == null) {
			jButton1 = new JButton();
			jButton1.setBackground(SystemColor.control);
			jButton1.setEnabled(false);
			jButton1.setToolTipText("Visualize the selected profile");
			jButton1.setBorder(javax.swing.BorderFactory.createBevelBorder(
					javax.swing.border.BevelBorder.RAISED));
			jButton1.setFont(new java.awt.Font("Microsoft Sans Serif", java.awt.Font.PLAIN, 11));
			jButton1.setBounds(new java.awt.Rectangle(134, 345, 132, 28));
			//			jButton1.setIcon(new ImageIcon(getClass().getResource("/pATT/icon/Open24.gif")));
			jButton1.setText("Visualize Profile");
			jButton1.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					//					algorithm = UserProfilingUI.eINSTANCE.getProfilingPanel().getProfilingAlgortihm();
					visualizeProfile();
					jButton1.setEnabled(false);
				}
			});
		}
		return jButton1;
	}
	/**
	 * This method initializes jButton1
	 *
	 * @return javax.swing.JButton
	 */
	public JButton getJButtonSave() {
		if (jButtonSave  == null) {
			jButtonSave = new JButton();
			jButtonSave.setBackground(SystemColor.control);
			jButtonSave.setEnabled(false);
			jButtonSave.setToolTipText("Visualize the selected profile");
			jButtonSave.setBorder(javax.swing.BorderFactory.createBevelBorder(
					javax.swing.border.BevelBorder.RAISED));
			jButtonSave.setIcon(new ImageIcon(getClass().getResource("/pATT/icon/Save24.gif")));
			jButtonSave.setFont(new java.awt.Font("Microsoft Sans Serif", java.awt.Font.PLAIN, 11));
			jButtonSave.setBounds(new java.awt.Rectangle(534, 345, 132, 28));
			//			jButtonSave.setIcon(new ImageIcon(getClass().getResource("/pATT/icon/Open24.gif")));
			jButtonSave.setText("Save Image");
			jButtonSave.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					resol.show();   
					getJButtonSave().setEnabled(false);
					
//					TreeVisualizer.saveComponentAsJPEG(panel, this,"C:/Documents and Settings/Ignacio/Escritorio/ACA.jpg");
				}
			});
		}
		return jButtonSave;
	}
	
	/**
	 * This method initializes jChooserButton
	 *
	 * @return javax.swing.JButton
	 */
	public JButton getJChooserButton() {
		if (jChooserButton == null) {
			jChooserButton = new JButton();
			jChooserButton.setEnabled(false);
			jChooserButton.setBorder(javax.swing.BorderFactory.createBevelBorder(
					javax.swing.border.BevelBorder.RAISED));
			jChooserButton.setBounds(new java.awt.Rectangle(15, 15, 131, 26));
			jChooserButton.setToolTipText("Choose a created profile");
			jChooserButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					setEnabled(false);
					jTree = null;
					getJScrollPane3().setViewportView(getJTree());
					getJScrollPane3().setVisible(true);
					getJTree().setVisible(true);
					UserProfilingUI.eINSTANCE.setEnabled(false);
					getJWindow().show();
				}
			});
			jChooserButton.setText(Message.CHOOSE);
		}
		return jChooserButton;
	}
	/**
	 * This method initializes jPanel2
	 *
	 * @return javax.swing.JPanel
	 */
	public JPanel getJVisualizePanel() {
		if (jVisualizePanel == null) {
			jVisualizePanel = new JPanel();
			jVisualizePanel.setLayout(null);
			jVisualizePanel.setBackground(SystemColor.control);
			jVisualizePanel.setEnabled(false);
			jVisualizePanel.add(getJButton1(), null);
			jVisualizePanel.add(getJButtonSave(), null);
			jVisualizePanel.add(getJPanel3(), null);
			jVisualizePanel.add(getJChooserPanel1(), null);
		}
		return jVisualizePanel;
	}
	
	/**Retorna una instancia del algoritmo de Visualize,
	 * dado el nombre del mismo
	 *
	 * */
	public static VisualizeAlgorithm getVisualizeAlgorithm(String name) {
		String nameClass = Message.PATH_VIS_ALGORITHM + name;
		
		VisualizeAlgorithm algorithm = null;
		try {
			algorithm = (VisualizeAlgorithm) Class.forName(nameClass).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return algorithm;
	}
	/**
	 * Documentacion pendiente.
	 *
	 * @return (documentacion pendiente).
	 */
	public JWindow getJWindow() {
		if (jWindow == null) {
			jWindow = new JWindow();
		}
		jWindow.setSize(new java.awt.Dimension(184, 200));
		jWindow.setLocation(getJChooserButton().getLocationOnScreen());
		jWindow.setContentPane(getJScrollPane3());
		
		return jWindow;
	}
	/**
	 * Documentacion pendiente.
	 *
	 * @param nameProfile requerido.
	 * @param algoritm requerido.
	 */
	public void updateProfile(String nameProfile, ProfilingAlgorithm algoritm) {
		algoritms.put(nameProfile, algoritm);
	}
	
	/**Retorna un ProfilingAlgorithm dado el nombre de un perfil seleccionado*/
	protected ProfilingAlgorithm getSelectedAlgoritm(String name) {
		return this.algoritms.get(name);
	}
	/**
	 * Documentacion pendiente.
	 */
	protected void visualizeProfile() {
		getJPanel().removeAll();
		getJPanel().updateUI();
		
		int count = 1;
		jProgressBar.setMinimum(count);
		jProgressBar.setMaximum(4);
		jProgressBar.setString("processing...");
		jProgressBar.setValue(count);
		jProgressBar.setStringPainted(true);
		
		String nameAlgorithm = this.algorithm.getClass().getSimpleName();
		Logger.log(Message.APPLY_VIS_ALGORITHM);
		String nameVis = hash.get(nameAlgorithm);
		if (nameVis != null) {
			jProgressBar.setValue(count++);
			visAlgorithm = (VisualizeAlgorithm) getVisualizeAlgorithm(nameVis);
			jProgressBar.setValue(count++);
			try {
				panel = visAlgorithm.visualizeProfile(algorithm);
				
				if(visAlgorithm.canSave()){
					getJButtonSave().setEnabled(true);
				}else{
					getJButtonSave().setEnabled(false);
				}
				
			} catch (Exception e) {
				jProgressBar.setValue(0);
				jProgressBar.setString("");
				JOptionPane.showMessageDialog(null, Message.ERROR_VISUALIZAR,
						Message.ERROR_VISUALIZAR_TILLE, JOptionPane.ERROR_MESSAGE);
			}
			jProgressBar.setValue(count++);
			getJPanel().add(panel, null);
			jProgressBar.setValue(count++);
			jProgressBar.setString("finish...");
		} else {
//			jProgressBar.setValue(0);
//			jProgressBar.setString("");
//			JOptionPane.showMessageDialog(this, Message.ERROR_VISUALIZAR_ALG,
//					Message.ERROR_VISUALIZAR_TILLE, JOptionPane.ERROR_MESSAGE);
			
			jProgressBar.setValue(count++);
			jProgressBar.setValue(count++);
			getJTextArea().setText("\n \n"+algorithm.toText());
			jProgressBar.setValue(count++);
			getJPanel().add(getJScrollPane4(), null);
			jProgressBar.setValue(count++);
			jProgressBar.setString("finish...");
			
		}
	}
	
	
	/**
	 * This method initializes jScrollPane4	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane4() {
		if (jScrollPane4  == null) {
			jScrollPane4 = new JScrollPane();
			jScrollPane4.setViewportView(getJTextArea());
			jScrollPane4.setBackground(SystemColor.control);
			jScrollPane4.setBounds(new java.awt.Rectangle(10, 15, 756, 270));
		}
		return jScrollPane4;
	}

	/**
	 * This method initializes jTextArea	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getJTextArea() {
		if (jTextArea  == null) {
			jTextArea = new JTextArea();
			jTextArea.setEditable(false);
			jTextArea.setFont(new java.awt.Font("Microsoft Sans Serif", java.awt.Font.PLAIN, 11));
		}
		return jTextArea;
	}

	
	/**
	 * This method initializes jChooseTextField
	 *
	 * @return javax.swing.JTextField
	 */
	private JTextField getJChooseTextField() {
		if (jChooseTextField == null) {
			jChooseTextField = new JTextField();
			jChooseTextField.setBounds(new java.awt.Rectangle(148, 15, 623, 26));
			jChooseTextField.setEditable(false);
			jChooseTextField.setFont(new java.awt.Font("Microsoft Sans Serif", java.awt.Font.BOLD,
					11));
			//			jChooseTextField.setName("Show the selected profile");
			jChooseTextField.setText("");
			jChooseTextField.setBackground(java.awt.Color.white);
			jChooseTextField.setToolTipText("");
		}
		return jChooseTextField;
	}
	/**
	 * This method initializes jChooserPanel1
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getJChooserPanel1() {
		if (jChooserPanel1 == null) {
			jChooserPanel1 = new JPanel();
			jChooserPanel1.setLayout(null);
			jChooserPanel1.setBorder(BorderFactory.createTitledBorder(
					BorderFactory.createLineBorder(Color.blue, 1),
					"Profiles",
					TitledBorder.DEFAULT_JUSTIFICATION,
					TitledBorder.DEFAULT_POSITION,
					new Font("Microsoft Sans Serif", Font.PLAIN, 11),
					Color.blue));
			jChooserPanel1.add(getJChooserButton(), null);
			jChooserPanel1.add(getJChooseTextField(), null);
			jChooserPanel1.setBounds(new java.awt.Rectangle(5, 4, 777, 50));
		}
		return jChooserPanel1;
	}
	/**
	 * This method initializes jPanel
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			jPanel = new JPanel();
			jPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
					javax.swing.BorderFactory.createLineBorder(java.awt.Color.blue, 1),
					"",
					javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
					javax.swing.border.TitledBorder.DEFAULT_POSITION,
					new java.awt.Font("Microsoft Sans Serif", java.awt.Font.PLAIN, 11),
					java.awt.Color.blue));
			jPanel.setLayout(new BorderLayout());
			jPanel.setBounds(new java.awt.Rectangle(10, 15, 756, 270));
		}
		return jPanel;
	}
	/**
	 * This method initializes jPanel3
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getJPanel3() {
		if (jPanel3 == null) {
			jPanel3 = new JPanel();
			jPanel3.setLayout(null);
			jPanel3.setBounds(new java.awt.Rectangle(9, 57, 776, 325));
			jPanel3.setBackground(SystemColor.control);
			jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder(
					javax.swing.BorderFactory.createLineBorder(java.awt.Color.blue, 1),
					"Visualize Output",
					javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
					javax.swing.border.TitledBorder.DEFAULT_POSITION,
					new java.awt.Font("Microsoft Sans Serif", java.awt.Font.PLAIN, 11),
					java.awt.Color.blue));
			//			jPanel3.add(getJScrollPane1(), null);
			jPanel3.add(getJPanel(), null);
			jPanel3.add(getJProgressBar(), null);
		}
		return jPanel3;
	}
	
	/**
	 * This method initializes jProgressBar
	 *
	 * @return javax.swing.JProgressBar
	 */
	private JProgressBar getJProgressBar() {
		if (jProgressBar == null) {
			jProgressBar = new JProgressBar();
			jProgressBar.setBounds(new java.awt.Rectangle(618, 357, 152, 15));
		}
		return jProgressBar;
	}
	private JScrollPane getJScrollPane3() {
		if (jScrollPane3 == null) {
			jScrollPane3 = new JScrollPane();
			jScrollPane3.setBounds(new java.awt.Rectangle(5, 18, 291, 192));
			jScrollPane3.setVisible(false);
			jScrollPane3.setViewportView(getJTree());
		}
		return jScrollPane3;
	}
	private JTree getJTree() {
		if (jTree == null) {
			DefaultMutableTreeNode raiz = new DefaultMutableTreeNode(Message.VIS_ALGORITHM);
			Enumeration enum1 = this.algoritms.keys();
			while (enum1.hasMoreElements()) {
				String element = (String) enum1.nextElement();
				DefaultMutableTreeNode nodo = new DefaultMutableTreeNode(element);
				raiz.add(nodo);
			}
			jTree = new JTree(raiz);
			jTree.setSelectionRow(0);
			jTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
				public void valueChanged(javax.swing.event.TreeSelectionEvent e) {
					DefaultMutableTreeNode selection = (DefaultMutableTreeNode) jTree.getLastSelectedPathComponent();
					if (!selection.toString().equals(Message.VIS_ALGORITHM)) {
						//Se acomoda la interface
						algorithm = getSelectedAlgoritm(selection.toString());
						Logger.log(Message.CHOOSE_VIS_ALGORITHM + selection.toString());
						getJButton1().setEnabled(true);
						getJButtonSave().setEnabled(false);
						getJChooseTextField().setText(selection.toString());
					}
					//					setEnabled(true);
					getJScrollPane3().setVisible(false);
					getJTree().setVisible(false);
					getJWindow().dispose();
					//					la siguiente linea es para que quede selccionada la raiz
					getJTree().setSelectionRow(0);
					UserProfilingUI.eINSTANCE.setEnabled(true);
				}
			});
		}
		return jTree;
	}
	private void initialize() {
		hash.put(Message.ECTREE, Message.ECTREE_VIS);
		hash.put(Message.SAVER, Message.SAVER_VIS);
	}
	public void saveImage(int heigth, int width) {
		
		if (m_FileChooser == null) {
			m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		}
		m_FileChooser.setFileFilter(m_ProfFilter);
		int returnVal = m_FileChooser.showSaveDialog(this);
		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File sFile = m_FileChooser.getSelectedFile();
			try {
//				JPanel panelVis = visAlgorithm.getPanelVisualize().
				Utils.saveComponentAsJPEG(visAlgorithm.getPanelVisualize(),getJPanel(),sFile.getAbsolutePath()+".jpg", heigth, width);
			} catch (Exception ex) {
				JOptionPane.showMessageDialog(this,
						Message.ERROR_FILE_SAVE
						+ sFile.getName()
						+ "\n" + ex.getMessage(),
						Message.ERROR_FILE_SAVE_TITLE,
						JOptionPane.ERROR_MESSAGE);
			}
				JOptionPane.showMessageDialog(this,
						Message.INFO_SAVE,
						Message.INFO_SAVE_TITLE,
						JOptionPane.INFORMATION_MESSAGE);
				
				
				getJPanel().removeAll();
				getJPanel().repaint();
			Logger.log(Message.SAVE_PROFILE+sFile.getName());
		}
	}
	
}
